/** @file */
#include "list.h" /* struct film_s */
#include <string.h> /* memset() */


/**
 * list_add - dodaje nowy element do listy
 * @new: element do dodania
 * @head: glowa listy
 */
void list_add(film_s *nnew, film_s **head)
{
    film_s **pnt;

    /* znajdz wskaźnik który należy przypisać do wsk */
    pnt = head;
    while ( *pnt )
        pnt = &(*pnt)->next;

    /* przypisz nowy wskaźnik */
    *pnt = nnew;
    (*pnt)->next = NULL;
}

/**
 * @brief list_del usuwa element z listy
 * @param entry element do usunięcia
 * @param head głowa listy
 */
void list_del(film_s *entry, film_s **head)
{
    film_s *pnt;
    film_s *pnt_prev = NULL;

    if ( !head ) return;

    pnt = *head;
    /* idz do elementy listy o numerze numer */
    while ( pnt->next ) {
        if ( pnt == entry ) /* tu porównuje wskaźniki co do wartości */
            break;
        pnt_prev = pnt;
        pnt = pnt->next;
    }

    /* sprawdz czy mamy głowe czy jestesmy gdzieś w brzuchu */
    if ( pnt == *head ) {
        /* wykasuj głowe */
        *head = (*head)->next;
    } else {
        /* jesteśmy w brzuchy lub jesteśmy w butach ( bez różnicy
         * bo gddy jesteśmy w bucie, to pnt->next = NULL,
         * zatem wtedy przypisujemy pnt_poprzendi->next = NULL! */
        pnt_prev->next = pnt->next;
    }
}

/**
 * @brief list_sort sortuje liste
 * @param priv parametr do funckji
 * @param head głowa listy
 * @param cmp funkcja typu int (*)(void *priv, film_s *a, film_s *b) porównująca elementy a i b
 * implementacje sortowania bąbelkowego (buble sort)
 */
void list_sort(void *priv, struct film_s **head,
		int (*cmp)(void *priv, struct film_s *a,
			struct film_s *b))
{
    film_s head2;
    film_s *nhead = &head2;
    film_s *pnt;
    film_s *pnt_prev;

    /* przesuń głowe 1 poziom wyżej na nhead */
    if ( !head )
        return;
    if ( !*head )
        return;

    /* głowa wcześniej */
    nhead->next = *head;

    for (pnt_prev = nhead, pnt = nhead->next;
         pnt && pnt->next;
         pnt_prev = pnt, pnt = pnt->next) {

         if ( (*cmp)(priv, pnt, pnt->next) > 0 ) {

            /* zamien ze sobą elementy pnt i pnt->next */
            pnt_prev->next = pnt->next;
            pnt->next = pnt->next->next;
            pnt_prev->next->next = pnt;

            /* pętla od początku*/
            pnt_prev = nhead;
            pnt = nhead->next;

        }

    }

    /* nadpisz głowe */
    *head = nhead->next;
}

